var _Status = require('./slotstatus.js');
var SLOT_BLOCK = _Status.SLOT_BLOCK;
var SLOT_OVER = _Status.SLOT_OVER;// over an empty cell
var SLOT_MERGE = _Status.SLOT_MERGE;// will merge after movement

// ==========================
// Data
// ==========================
function Data(lines) {
    this.mClone = [];
    for (var i = 0; i < lines; i++) {
        this.mClone.push(0);
    }
    this.mEmpty = 0;
    this.mMerge = 0;
}
Data.prototype.init = function (state) {
    this.mEmpty = 0;
    this.mMerge = 0;
    for (var i = 0; i < state.length; i++) {
        if (state[i] == SLOT_BLOCK) {
            this.mClone[i] = -1;
        } else {
            this.mClone[i] = 0;
            this.mEmpty++;
        }
    }
    return this;
};
Data.prototype.initPrivileged = function (state, privilege) {
    this.mEmpty = 0;
    this.mMerge = 0;
    for (var i = 0; i < state.length; i++) {
        if (state[i] == SLOT_BLOCK) {
            this.mClone[i] = -1;
        } else {
            if (privilege[i] > 0) {
                this.mClone[i] = 1;
                this.mMerge++;
            } else {
                this.mClone[i] = 0;
                this.mEmpty++;
            }
        }
    }
    return this;
};
Data.prototype.emptyCount = function () {
    return this.mEmpty;
};
Data.prototype.mergeCount = function () {
    return this.mMerge;
};
Data.prototype.getEmptyIndex = function (index) {
    for (var i = 0; i < this.mClone.length; i++) {
        if (this.mClone[i] == 0) {
            if (index == 0) {
                return i;
            }
            index--;
        }
    }
    return -1;
};
Data.prototype.getMergeIndex = function (index) {
    for (var i = 0; i < this.mClone.length; i++) {
        if (this.mClone[i] == 1) {
            if (index == 0) {
                return i;
            }
            index--;
        }
    }
    return -1;
};
Data.prototype.toString = function () {
    return JSON.stringify({
        merged: this.mMerge, empty: this.mEmpty, data: this.mClone
    });
};

// ==========================
// Slot
// ==========================
function SlotSnap(lines) {
    this.mBlockCount = 0;
    this.mMergeCount = 0;
    // SLOT_OVER moved
    // SLOT_MERGE can merge
    // SLOT_BLOCK all line blocked

    this.mStatus = [];
    for (var i = 0; i < lines; i++) {
        this.mStatus.push(0);
    }
    this.mData = new Data(lines);
}
SlotSnap.prototype.reset = function () {
    this.mBlockCount = 0;
    this.mMergeCount = 0;
};
SlotSnap.prototype.getData = function () {
    return this.mData.init(this.mStatus);
};
SlotSnap.prototype.getPrivilegedData = function (privilege) {
    return this.mData.initPrivileged(this.mStatus, privilege);
};
SlotSnap.prototype.getMergeCount = function () {
    return this.mMergeCount;
};
SlotSnap.prototype.setState = function (line, state) {
    this.mStatus[line] = state;
    if (state == SLOT_MERGE) {
        this.mMergeCount++;
    } else if (state == SLOT_BLOCK) {
        this.mBlockCount++;
    }
};
SlotSnap.prototype.toString = function () {
    var str = '-----------\n';
    str += 'merge:' + this.mMergeCount + ',block:' + this.mBlockCount + '\n';
    for (var i = 0; i < this.mStatus.length; i++) {
        switch (this.mStatus[i]) {
            case SLOT_OVER:
                str += '>>';
                break;
            case SLOT_MERGE:
                str += '>*';
                break;
            case SLOT_BLOCK:
                str += '>|';
                break;
            case -1:
                str += '[]';
                break;
        }
        str += '\n';
    }
    return str;
};
SlotSnap.prototype.randomLine = function () {
    var index = 0;
    if (this.mMergeCount > 0) {
        // random in merged
        index = Math.floor(Math.random() * this.mMergeCount);
        for (var i = 0; i < this.mStatus.length; i++) {
            if (this.mStatus[i] == SLOT_MERGE) {
                if (index == 0) {
                    return i;
                }
                index--;
            }
        }
    } else {
        if (this.mBlockCount == this.mStatus.length) {
            return -1;
        }
        // random in not merged
        index = Math.floor(Math.random() * (this.mStatus.length - this.mMergeCount));
        for (var i = 0; i < this.mStatus.length; i++) {
            if (this.mStatus[i] != SLOT_BLOCK) {
                if (index == 0) {
                    return i;
                }
                index--;
            }
        }
    }

    return -1;
};

module.exports = SlotSnap;